package com.feimt.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeCloseRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeQueryRequest;
import com.alipay.api.response.AlipayTradeCloseResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeQueryResponse;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.feimt.pojo.Orderlog;
import com.feimt.pojo.Orders;
import com.feimt.service.AlipayService;
import com.feimt.service.OrderService;
import com.feimt.service.OrderlogService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.ReentrantLock;

@Slf4j
@Service
public class AlipayServiceImpl implements AlipayService {
    @Autowired
    private AlipayClient alipayClient;
    @Value("${ali-pay.return-url}")
    private String returnUrl;
    @Value("${ali-pay.notify-url}")
    private String notifyUrl;

    /**
     * 发起支付接口
     * @param orders  订单对象
     * @return 支付页面字符串
     */
    @Override
    public String tradeCreate(Orders orders) {
        try {
            // 创建订单
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            //异步接收地址，仅支持http/https，公网可访问
            request.setNotifyUrl(notifyUrl);
            //同步跳转地址，仅支持http/https
            request.setReturnUrl(returnUrl);

            /******必传参数******/
            JSONObject bizContent = new JSONObject();
            //商户订单号，商家自定义，保持唯一性
            bizContent.put("out_trade_no", orders.getId());
            //支付金额，最小值0.01元
            bizContent.put("total_amount", orders.getAmount());
            //订单标题，不可使用特殊符号
            bizContent.put("subject", "用户 "+orders.getUserName() + "下单~~~");
            //电脑网站支付场景固定传值FAST_INSTANT_TRADE_PAY
            bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY");

            /******可选参数******/
            //bizContent.put("time_expire", "2022-08-01 22:00:00");
            //// 商品明细信息，按需传入
            //JSONArray goodsDetail = new JSONArray();
            //JSONObject goods1 = new JSONObject();
            //goods1.put("goods_id", "goodsNo1");
            //goods1.put("goods_name", "子商品1");
            //goods1.put("quantity", 1);
            //goods1.put("price", 0.01);
            //goodsDetail.add(goods1);
            //bizContent.put("goods_detail", goodsDetail);

            //// 扩展信息，按需传入
            //JSONObject extendParams = new JSONObject();
            //extendParams.put("sys_service_provider_id", "2088511833207846");
            //bizContent.put("extend_params", extendParams);

            request.setBizContent(bizContent.toString());
            //执行请求、调用支付宝接口
            AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
            if(response.isSuccess()){
                System.out.println("支付宝接口调用成功");
                log.info("调用成功，返回结果==》{}",response.getBody());
            } else {
                System.out.println("支付宝接口调用失败");
                log.info("调用失败，返回结果==》code:{},body:{}",response.getCode(),response.getMsg());
            }
            //返回 跳转表单
            return response.getBody();
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "下单失败";
    }

    @Autowired
    private OrderService orderService;
    @Autowired
    private OrderlogService orderlogService;
    //定义 常量锁
    private final ReentrantLock lock = new ReentrantLock();
    /**
     * 订单业务状态修改
     * @param params
     * @return
     */
    @Override
    public String processOrder(Map<String, String> params) {
        log.info("处理订单");
        //获取订单号
        String orderNo = params.get("out_trade_no");
        String flag = "failure";
        if(lock.tryLock()){
            try {
                //更新订单状态
                LambdaUpdateWrapper<Orders> wrapper = new LambdaUpdateWrapper<>();
                wrapper.set(Orders::getStatus, 2);
                wrapper.eq(Orders::getId, orderNo);
                orderService.update(wrapper);

                //记录支付日志
                Orderlog orderLog = new Orderlog();
                orderLog.setText(JSON.toJSONString(params));
                orderlogService.save(orderLog);
                flag = "success";
                log.info("订单状态修改为待配送2");
            } finally {
                lock.unlock();
            }
        }
        return flag;
    }


    /**
     * 用户取消订单
     * @param orderId
     */
    @Override
    public void cancelOrder(String orderId) {
        //调用支付宝提供的统一收单交易关闭接口
        this.closeOrder(orderId);
        //更新用户订单状态
        LambdaUpdateWrapper<Orders> wrapper = new LambdaUpdateWrapper<>();
        wrapper.set(Orders::getStatus,5);
        wrapper.eq(Orders::getId,orderId);
        orderService.update(wrapper);
    }

    /**
     * 关单接口的调用
     * @param orderId 订单号
     */
    private void closeOrder(String orderId) {
        try {
            log.info("关单接口的调用,订单号 ===>{}", orderId);
            AlipayTradeCloseRequest request = new AlipayTradeCloseRequest();
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", orderId);
            request.setBizContent(bizContent.toString());
            AlipayTradeCloseResponse response = alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("调用成功,返回结果===>"+response.getBody());
            } else {
                log.info("调用失败,返回码"+response.getCode()+",返回描述"+response.getMsg());
                //throw new RuntimeException("关单接口的调用失败");
            }
        }catch(AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("关单接口的调用失败");
        }
    }


    /**
     * 查询订单
     * @param orderId
     * @return 返回订单查询结果，如果返回null则表示支付宝端尚未创建订单
     */
    @Override
    public String queryOrder(String orderId) {
        try {
            log.info("查单接口调用 ===> {}", orderId);
            AlipayTradeQueryRequest request = new AlipayTradeQueryRequest();
            JSONObject bizContent = new JSONObject();
            bizContent.put("out_trade_no", orderId);
            request.setBizContent(bizContent.toString());
            AlipayTradeQueryResponse response = alipayClient.execute(request);
            if(response.isSuccess()){
                log.info("调用成功，返回结果 ===> " + response.getBody());
                return response.getBody();
            } else {
                log.info("调用失败，返回码 ===> " + response.getCode() + ", 返回描述 ===> "
                        + response.getMsg());
                //throw new RuntimeException("查单接口的调用失败");
                return null;//订单不存在
            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
            throw new RuntimeException("查单接口的调用失败");
        }
    }


    /**
     * 从第0秒开始每隔30秒执行1次，查询创建超过5分钟，并且未支付的订单
     */
    @Scheduled(cron = "0/30 * * * * ?")
    public void orderConfirm(){
        LambdaQueryWrapper<Orders> qw = new LambdaQueryWrapper<>();
        qw.eq(Orders::getStatus, 1);
        // 获取当前时间的前两分钟
        Date time = new Date(new Date().getTime()-1000*60*1);
        log.info("time={}",time);
        qw.le(Orders::getCheckoutTime,time);
        List<Orders> ordersList = orderService.list(qw);

        for (Orders orders : ordersList) {
            log.info("订单超时：{}",orders);
            LambdaUpdateWrapper<Orders> uw = new LambdaUpdateWrapper<>();
            uw.set(Orders::getStatus,5);
            uw.eq(Orders::getId,orders.getId());
            orderService.update(uw);
            // 关闭支付宝支付接口
            closeOrder(orders.getId().toString());
        }
    }

}